home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 43.zip / Sources C- WorkDisk V.adf / ex / one.window.c < prev    next >
C/C++ Source or Header  |  1987-02-15  |  16KB  |  562 lines

  1.  
  2.  
  3. /* "SIMPLE" demo showing the use of the Intuition windowing system.  
  4.  *
  5.  * Opens a graphics-window, that is also a console window.  When you click
  6.  * in the console window, it echos what you type.  RETURN key issues
  7.  * both a carriage return and a line feed.  When you click in the
  8.  * Graphics window, the console window reports the kinds of events
  9.  * that the graphics window IDCMP is seeing, except, of course for
  10.  * the CLOSEWINDOW gadget that causes a program exit.  Note that a 
  11.  * user will generally have either an IDCMP or a Console attached
  12.  * to a window, but not necessarily both.  (Or if both, then that
  13.  * window won't usually ask for RAWKEYS, to allow the console to 
  14.  * translate them for normal reporting.)
  15.  *
  16.  * No menu stuff is included, but the event handling is included
  17.  * for menu picks within the HandleEvent() function.
  18.  *
  19.  * Additionally, shows how to trap the right hand mouse button
  20.  * events for any given active window.
  21.  *
  22.  * Author:  Rob Peck, 12/18/85
  23.  */
  24.  
  25. /* DEFINES ********************************************************** */
  26.  
  27. #define HOWMUCHTIME 40000
  28.  
  29. #define SECONDS io_Actual
  30. #define MICROSECONDS io_Length
  31.  
  32. #define DEPTH 5
  33. #define WINDOWGADGETS (WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE)
  34.  
  35. #define INTUITION_MESSAGE (1<<intuitionMsgBit)
  36. #define TYPED_CHARACTER (1<<consoleReadBit)
  37. #define TIME_OUT (1<<timerMsgBit)
  38.  
  39. #define CloseConsole(x) CloseDevice(x)
  40.  
  41. /* INCLUDES ********************************************************** */
  42.  
  43. #include "exec/types.h"
  44. #include "exec/io.h"
  45. #include "exec/memory.h"
  46.  
  47. #include "graphics/gfx.h"
  48. #include "hardware/dmabits.h"
  49. #include "hardware/custom.h"
  50. #include "hardware/blit.h"
  51. #include "graphics/gfxmacros.h"
  52. #include "graphics/copper.h"
  53. #include "graphics/view.h"
  54. #include "graphics/gels.h"
  55. #include "graphics/regions.h"
  56. #include "graphics/clip.h"
  57. #include "exec/exec.h"
  58. #include "graphics/text.h"
  59. #include "graphics/gfxbase.h"
  60.  
  61. #include "devices/console.h"
  62. #include "devices/keymap.h"
  63. #include "devices/timer.h"
  64.  
  65. #include "libraries/dos.h"
  66. #include "graphics/text.h"
  67. #include "libraries/diskfont.h"
  68. #include "intuition/intuition.h"
  69.  
  70. /* EXTERNALS ***************************************************** */
  71.  
  72. extern struct Window *OpenWindow();
  73. extern struct Screen *OpenScreen();
  74. extern struct MsgPort *CreatePort();
  75. extern struct IOStdReq *CreateStdIO();
  76.  
  77. /* GLOBALS ****************************************************** */
  78.  
  79. USHORT class;
  80. USHORT code;
  81. USHORT qualifier;
  82. USHORT mode;        
  83. APTR address;        /* address of the gadget which we hit */
  84. SHORT xx=0;
  85. SHORT yy=0;
  86. SHORT xdir = 2;
  87. SHORT ydir = 0;
  88. SHORT xsize,ysize;
  89.  
  90. long IntuitionBase=0;
  91. long GfxBase=0;
  92.  
  93. struct NewWindow nwGraphics = {
  94.     20, 20,            /* start position        */
  95.     480, 160,         /* width, height         */
  96.     1, 2,            /* detail pen, block pen    */
  97.     GADGETUP | 
  98.     GADGETDOWN | 
  99.     MOUSEBUTTONS | 
  100.     MENUPICK | 
  101.     RAWKEY |      
  102.     /* --------- NOTE ------------------------------------
  103.      
  104.        If you ask for rawkeys for the IDCMP in a window to
  105.        which a console is attached, you will NOT get any
  106.        translated ordinary console keys from the console
  107.        device.  The IDCMP traps all keystrokes, both down
  108.        and up and transmits them to you... console device
  109.        never gets to see any of them.   Complile this
  110.        program with this RAWKEY item commented out and
  111.        you will get ordinary console keys echoed to the
  112.        window.  Otherwise, as it is configured now, you
  113.        get RAW keys only.
  114.  
  115.     ----------------------------------------------------- */ 
  116.     CLOSEWINDOW, 
  117.                 /* IDCMP flags             */
  118.     RMBTRAP | GIMMEZEROZERO | WINDOWGADGETS,
  119.                 /* window flags            */
  120.     NULL,            /* pointer to first user gadget */
  121.     NULL,            /* pointer to user checkmark    */ 
  122.     "Graphics Window",    /* window title     */ 
  123.     NULL,            /* pointer to screen    (later)    */
  124.     NULL,            /* pointer to superbitmap     */
  125.     50,40,200,100,         /* sizing limits min and max */
  126.     WBENCHSCREEN        /* type of screen in which to open */    
  127.     };
  128.  
  129. /* RMBTRAP says that when this window is active, there is no menu to
  130.  * be rendered.... so report all right mouse button transitions to 
  131.  * the user if MOUSEBUTTONS is specified for the IDCMP (and it is) */
  132.  
  133. struct IOStdReq *consoleWriteMsg;       /* I/O request block pointer */
  134. struct MsgPort *consoleWritePort;       /* a port at which to receive */
  135. struct IOStdReq *consoleReadMsg;      /* I/O request block pointer */
  136. struct MsgPort *consoleReadPort;          /* a port at which to receive */
  137.  
  138. char tohex(e) 
  139.     char e;
  140. {
  141.     return( (char)( e < 10 ? (e+'0') : (e-10+'A') ) );
  142. }
  143.  
  144. char topoffset[] = { 0x1b, '[', '7', '4', 'y', '\n', 0 };
  145.     /* NULL-terminated string to send to console to reset scrolling
  146.      * region for the console to 80 lines from the top, leave some
  147.      * room for the graphics rendering */
  148.  
  149. char linesonpage[] = { 0x1b, '[', '8','t', '\n', 0 };
  150.  
  151.  
  152. main()
  153. {
  154.     char letter;        /* one letter at a time from console */
  155.  
  156.     int problem,error;
  157.     int wakeupmask,timerMsgBit;
  158.     
  159.     struct Window *wG;
  160.     struct RastPort *rpG;
  161.     
  162.     struct IntuiMessage *message;    /* the message the IDCMP sends us */
  163.     
  164.     int consoleReadBit, intuitionMsgBit;
  165.         /* integers that represent the signal bit assigned for the
  166.           * console and for intuition's IDCMP on which one waits 
  167.           * for some input during a Wait() function call */
  168.  
  169.     struct MsgPort *timerport;              /* for timer communications */
  170.     struct IOStdReq *timermsg;              /* for timer */
  171.  
  172.     GfxBase = OpenLibrary("graphics.library", 0);
  173.     if (GfxBase == NULL)
  174.     {
  175.         printf("Unable to open graphics library\n");
  176.         goto cleanup1;
  177.     }
  178.     IntuitionBase = OpenLibrary("intuition.library", 0);
  179.     if (IntuitionBase == NULL)
  180.     {
  181.         printf("Unable to open intuition library\n");
  182.         goto cleanup1;
  183.     }
  184.  
  185.         timerport = CreatePort(0,0);
  186.         if (timerport == 0) goto cleanup1;
  187.         timermsg = CreateStdIO(timerport);
  188.         if (timermsg == 0) goto cleanup1a;
  189.  
  190.     wG = OpenWindow(&nwGraphics);    /* open a window for graphics*/
  191.     if ( wG == NULL )
  192.     {
  193.         printf ("\nCouldnt open a window");
  194.         goto cleanup2;
  195.     }
  196.  
  197.     rpG = wG->RPort;    /* set a rastport pointer for both windows */
  198.  
  199.     /* create ports and messages for communicating with the console */
  200.  
  201.         consoleWritePort = CreatePort("my.con.write",0);
  202.         if(consoleWritePort == 0)
  203.                 { problem = 5; goto cleanup5; }
  204.         consoleWriteMsg =  CreateStdIO(consoleWritePort);
  205.         if(consoleWritePort == 0)
  206.                 { problem = 6; goto cleanup6; }
  207.  
  208.         consoleReadPort = CreatePort("my.con.read",0);
  209.         if(consoleReadPort == 0)
  210.                 { problem = 7; goto cleanup7; }
  211.         consoleReadMsg =  CreateStdIO(consoleReadPort);
  212.         if(consoleReadPort == 0)
  213.                 { problem = 8; goto cleanup8; }
  214.  
  215.     /* now attach a console to the window provided for its use */
  216.  
  217.         error = OpenConsole(consoleWriteMsg,consoleReadMsg,wG);
  218.         if(error != 0)
  219.                 { problem = 10; goto cleanup10; }
  220.                 /* attach a console to this window, initialize
  221.                  * for both write and read */
  222.  
  223.     /* Initialize the timer */
  224.         if (init_timer(timermsg) != 0) goto cleanup10;
  225.  
  226.     /* ask for the first timing interval */
  227.     /* 40,000 microseconds = .04 sec */
  228.     set_timer(timermsg,0,HOWMUCHTIME);
  229.  
  230.     /* tell console where to put a character that 
  231.      * it wants to give me queue up first read */
  232.  
  233.         QueueRead(consoleReadMsg,&letter); 
  234.  
  235.     /* reset the top offset to leave room for graphics */
  236.     ConPutStr(consoleWriteMsg,&topoffset[0]);
  237.     /* reset the number of lines on the page for text */
  238.     ConPutStr(consoleWriteMsg,&linesonpage[0]);
  239.  
  240.         ConWrite(consoleWriteMsg,"\fHello, World\r\n",15);
  241.  
  242.     ConWrite(consoleWriteMsg,"I will echo what\r\n you type\r\n",-1);
  243.     /* (use the variable length ... -1 ... function of ConWrite) */
  244.  
  245.     ConWrite(consoleWriteMsg,"Hit close gadget\r\n to exit",-1);
  246.     
  247. /* find out which signals to wait for.... Intuition allocates a signal bit
  248.  * for an IDCMP and the call to OpenConsole allocates a different bit */
  249.  
  250.     consoleReadBit = consoleReadPort->mp_SigBit;
  251.     intuitionMsgBit = wG->UserPort->mp_SigBit;
  252.     timerMsgBit = timerport->mp_SigBit;
  253.  
  254. /* this code assumes that the only events we expect to wake up for are
  255.  * characters typed to the console or messages from intuition arriving at
  256.  * the IDCMP */
  257.  
  258. /*  Wait for a CLOSEWINDOW or other event from intuition as well as
  259.  *  waiting for a typed character */
  260.  
  261.     do 
  262.     {
  263.         wakeupmask = Wait( INTUITION_MESSAGE | 
  264.                   TYPED_CHARACTER |
  265.                   TIME_OUT );
  266.  
  267.         /* if an intuition message, copy the contents of the
  268.          * message to some global variables (our own local 
  269.          * copy of the message) and reply immediately */
  270.  
  271.         if(wakeupmask & INTUITION_MESSAGE)
  272.         {
  273.             while( (message = (struct IntuiMessage *)
  274.                  GetMsg(wG->UserPort) ) != NULL)
  275.             {
  276.                 /* EMPTY THE PORT!!!! */
  277.                 /* make a local copy of the 
  278.                  * message before replying, and
  279.                  * then try to handle the event */
  280.                 class = message->Class;
  281.                 code =  message->Code;
  282.                 qualifier = message->Qualifier;
  283.                 address = message->IAddress;
  284.                 ReplyMsg(message);
  285.                 if(HandleEvent() == FALSE) break;
  286.             }
  287.         }
  288.          if(wakeupmask & TYPED_CHARACTER)
  289.         {
  290.             /* Task woke up because a message arrived
  291.              * at this port, so we must remove the 
  292.              * message from the port to allow its reuse 
  293.              */
  294.             GetMsg(consoleReadPort);
  295.  
  296.             /* Console character was read into 'letter'
  297.              */
  298.             ConPutChar(consoleWriteMsg,letter);
  299.             if(letter == '\r')
  300.                 ConPutChar(consoleWriteMsg,'\n');
  301.             /* added a line feed to a carriage return */
  302.  
  303.             /* Now that have typed the character, must
  304.              * send off another read request 
  305.              */ 
  306.             QueueRead(consoleReadMsg, &letter);
  307.         }
  308.          if(wakeupmask & TIME_OUT)
  309.         {
  310.             /* Task woke up because of a timeout;  that 
  311.              * is, the timer completed and returned its
  312.              * message to the reply port */
  313.             GetMsg(timerport);
  314.         
  315.             drawSomething(wG);
  316.             set_timer(timermsg,0,HOWMUCHTIME);    
  317.         }
  318.      
  319.     } while (HandleEvent());    /* keep going as long as 
  320.                          * HandleEvent returns nonzero */
  321.     problem = 0;
  322.  
  323.     AbortIO(consoleReadMsg);    /* cancel the last queued read */
  324.  
  325.         CloseConsole(consoleWriteMsg);
  326.  
  327.    cleanup10:
  328.    cleanup8:
  329.         DeleteStdIO(consoleReadMsg);
  330.    cleanup7:
  331.         DeletePort(consoleReadPort);
  332.    cleanup6:
  333.         DeleteStdIO(consoleWriteMsg);
  334.    cleanup5:
  335.         DeletePort(consoleWritePort);
  336.    cleanup3:
  337.     CloseWindow(wG);
  338.    cleanup2:
  339.     if (GfxBase != NULL) CloseLibrary(GfxBase);
  340.  
  341.     AbortIO(timermsg);
  342.  
  343.     DeleteStdIO(timermsg);
  344.    cleanup1a:
  345.     DeletePort(timerport);
  346.    cleanup1:
  347.         if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
  348.         if(problem > 0) 
  349.         exit(problem+1000);
  350.     else
  351.         return(0);
  352. }
  353.  
  354. drawSomething(w)
  355. struct Window *w;
  356. {
  357.     struct RastPort *rp;
  358.     SHORT xsize, ysize;
  359.     rp = w->RPort;
  360.     xsize = w->Width;    /* use current size limits for the window */
  361.     ysize = (w->Height)/2;  /* draw only in top half of window */
  362.     SetAPen(rp,RangeRand(4));    /* can even draw in background color */
  363.     Move(rp, RangeRand(xsize), RangeRand(ysize));
  364.     Draw(rp, RangeRand(xsize), RangeRand(ysize));
  365.     return(0);
  366. }
  367.  
  368. HandleEvent()
  369. {
  370.     switch(class) 
  371.     {
  372.         case CLOSEWINDOW:
  373.             return(FALSE);    /* cleanup and exit if close
  374.                      * gadget is hit */
  375.             break;
  376.         /* could have provided processing for each of these */
  377.         case RAWKEY:
  378.                         ConPutStr(consoleWriteMsg,"\n\rRAWKEY event:\n\r");
  379.                         ConPutStr(consoleWriteMsg,"value = ");
  380.                         ConPutChar(consoleWriteMsg,
  381.                                         (tohex((code & 0xf0)>>4)));
  382.                         ConPutChar(consoleWriteMsg,(tohex(code & 0x0f)));
  383.                         break;
  384.         case GADGETUP:
  385.             break;    /* event not in use */
  386.         case GADGETDOWN:
  387.             break;    /* event not in use */
  388.         case MOUSEBUTTONS:
  389.              ConPutStr(consoleWriteMsg,"\n\rMOUSEBUTTONS event=");
  390.              switch(code)
  391.              {
  392.             case SELECTDOWN:
  393.                   ConPutStr(consoleWriteMsg,"\n\rSELECTDOWN\n\r");
  394.                 break;
  395.             case SELECTUP:
  396.                   ConPutStr(consoleWriteMsg,"\n\rSELECTUP\n\r");
  397.                 break;
  398.             case MENUDOWN:
  399.                   ConPutStr(consoleWriteMsg,
  400.                     "\n\rMENUDOWN\n\r");
  401.                 break;
  402.             case MENUUP:
  403.                   ConPutStr(consoleWriteMsg,
  404.                     "\n\rMENUUP\n\r");
  405.                 break;
  406.              }
  407.     }
  408.     class = 0; code = 0; qualifier = 0; address = 0;
  409.     return(TRUE);
  410. }
  411.  
  412.  
  413. /* These functions are taken directly from the console.device chapter
  414.  * in the Amiga V1.1 ROM KERNEL manual. */
  415.  
  416.  
  417. /* Open a console device */
  418.  
  419.     /* this function returns a value of 0 if the console 
  420.      * device opened correctly and a nonzero value (the error
  421.      * returned from OpenDevice) if there was an error.
  422.      */
  423.     
  424.     int
  425. OpenConsole(writerequest,readrequest,window)
  426.     struct IOStdReq *writerequest;
  427.     struct IOStdReq *readrequest;
  428.     struct Window *window;
  429.     {    
  430.         int error;    
  431.             writerequest->io_Data = (APTR) window;
  432.             writerequest->io_Length = sizeof(*window);
  433.             error = OpenDevice("console.device", 0, writerequest, 0);
  434.         readrequest->io_Device = writerequest->io_Device;
  435.         readrequest->io_Unit   = writerequest->io_Unit;
  436.             /* clone required parts of the request */
  437.         return(error);    
  438.     }
  439.  
  440. /* Output a single character to a specified console */ 
  441.  
  442.     int
  443. ConPutChar(request,character)
  444.     struct IOStdReq *request;
  445.     char character;
  446.     {
  447.             request->io_Command = CMD_WRITE;
  448.             request->io_Data = (APTR)&character;
  449.             request->io_Length = 1;
  450.             DoIO(request);
  451.         /* command works because DoIO blocks until command is
  452.          * done (otherwise pointer to the character could become
  453.          * invalid in the meantime).
  454.          */
  455.         return(0);
  456.     }
  457.  
  458. /* Output a stream of known length to a console */ 
  459.  
  460.     int
  461. ConWrite(request,string,length)
  462.     struct IOStdReq *request;
  463.     char *string;
  464.     int length;
  465.     {
  466.             request->io_Command = CMD_WRITE;
  467.             request->io_Data = (APTR)string;
  468.             request->io_Length = length; 
  469.             DoIO(request);
  470.         /* command works because DoIO blocks until command is
  471.          * done (otherwise pointer to string could become
  472.          * invalid in the meantime).
  473.          */
  474.         return(0);
  475.     }
  476.  
  477. /* Output a NULL-terminated string of characters to a console */ 
  478.  
  479.     int
  480. ConPutStr(request,string)
  481.     struct IOStdReq *request;
  482.     char *string;
  483.     {
  484.             request->io_Command = CMD_WRITE;
  485.             request->io_Data = (APTR)string;
  486.             request->io_Length = -1;  /* tells console to end when it
  487.                        * sees a terminating zero on
  488.                        * the string. */
  489.             DoIO(request);
  490.         return(0);
  491.     }
  492.     
  493.     /* queue up a read request to a console, show where to
  494.      * put the character when ready to be returned.  Most
  495.      * efficient if this is called right after console is
  496.      * opened */
  497.  
  498.     int
  499. QueueRead(request,whereto)
  500.     struct IOStdReq *request;
  501.     char *whereto;
  502.     {
  503.             request->io_Command = CMD_READ;
  504.             request->io_Data = (APTR)whereto;
  505.             request->io_Length = 1;
  506.             SendIO(request);
  507.         return(0);
  508.     }
  509.  
  510.     /* see if there is a character to read.  If none, don't wait, 
  511.      * come back with a value of -1 */
  512.  
  513.     int 
  514. ConMayGetChar(request,requestPort, whereto)
  515.     struct IOStdReq *request;
  516.     char *whereto;
  517.     {
  518.             register temp;
  519.  
  520.             if ( GetMsg(requestPort) == NULL ) return(-1);
  521.             temp = *whereto;
  522.             QueueRead(request,whereto);
  523.             return(temp);
  524.     }
  525.  
  526.     /* go and get a character; put the task to sleep if
  527.      * there isn't one present */
  528.  
  529.     UBYTE
  530. ConGetChar(consolePort,request,whereto)
  531.     struct IOStdReq *request; 
  532.     struct MsgPort *consolePort;   
  533.         char *whereto;
  534.     {
  535.         register UBYTE temp;
  536.         while((GetMsg(consolePort) == NULL)) WaitPort(consolePort);
  537.         temp = *whereto;    /* get the character */
  538.         QueueRead(request,whereto);
  539.         return(temp);
  540.     }
  541.             
  542. int 
  543. init_timer(tmsg)    /* return an error code if timer did not open */
  544. {
  545.         return( OpenDevice(TIMERNAME,UNIT_VBLANK,tmsg,0));
  546. }
  547.  
  548.  
  549. int
  550. set_timer(tmsg,sec,micro)
  551. ULONG sec,micro;
  552. struct IOStdReq *tmsg;
  553. {
  554.         tmsg->io_Command = TR_ADDREQUEST;    /* add a new timer request */
  555.         tmsg->SECONDS = sec;        /* seconds */
  556.         tmsg->MICROSECONDS = micro; /* microseconds */
  557.         SendIO( tmsg );             /* post a request to the timer */
  558.         return(0);
  559. }
  560.  
  561.  
  562.